#include "formatchange.h"

FormatChange::FormatChange()
{
	init();
}

FormatChange::FormatChange(int newRev, int newUser, int newDoc, int newPos, int newNum) :
		Change(Message::CHANGE_FORMAT, newRev, newUser, newDoc, newPos)
{
	init();

	num = newNum;
}

FormatChange::FormatChange(QByteArray bytes)
{
	quint8 tmpChar;
	QDataStream sin(bytes);

	init();

	//get the operation
	sin >> tmpChar;
	operation = tmpChar;

	sin >> revisionId >> userId >> docId >> position >> num;

	while (!sin.atEnd())
	{
		sin >> tmpChar;	//get the formatType

		if (sin.atEnd())
			break;

		if ((formatType)tmpChar == FormatChange::BOLD)
		{
			quint8 tmpInt;
			sin >> tmpInt;
			bold = QFont::Weight(tmpInt);

			boldChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::ITALICS)
		{
			sin >> italics;

			italicsChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::UNDERLINE)
		{
			sin >> underline;

			underlineChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::FONT_SIZE)
		{
			sin >> fontSize;

			fontSizeChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::FONT_FAMILY)
		{
			char* newData = NULL;
			sin >> newData;
			fontFamily = QString(newData);
			delete [] newData;

			fontFamilyChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::FORE_COLOUR)
		{
			quint32 tmpInt;
			sin >> tmpInt;
			foreColour = (QRgb)tmpInt;

			foreColourChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::BACK_COLOUR)
		{
			quint32 tmpInt;
			sin >> tmpInt;
			backColour = (QRgb)tmpInt;

			backColourChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::ALIGN)
		{
			quint32 tmpInt;
			sin >> tmpInt;
			align = Qt::Alignment(tmpInt);

			alignChanged = true;
		}
		else if ((formatType)tmpChar == FormatChange::LIST)
		{
			quint32 tmpInt;
			sin >> tmpInt;
			list = (int)tmpInt;

			listChanged = true;
		}
	}
}

void FormatChange::init()
{
	operation = (quint8)Message::CHANGE_FORMAT;

	boldChanged = false;
	italicsChanged = false;
	underlineChanged = false;
	fontSizeChanged = false;
	fontFamilyChanged = false;
	foreColourChanged = false;
	backColourChanged = false;
	alignChanged = false;
	listChanged = false;
}

void FormatChange::setBold(int newBold)
{
	bold = (QFont::Weight)newBold;
	boldChanged = true;
}

void FormatChange::setItalics(bool newItalics)
{
	italics = newItalics;
	italicsChanged = true;
}

void FormatChange::setUnderline(bool newUnderline)
{
	underline = newUnderline;
	underlineChanged = true;
}

void FormatChange::setFontSize(int newFontSize)
{
	fontSize = newFontSize;
	fontSizeChanged = true;
}

void FormatChange::setFontFamily(QString newFontFamily)
{
	fontFamily = newFontFamily;
	fontFamilyChanged = true;
}

void FormatChange::setForeColour(QRgb newForeColour)
{
	foreColour = newForeColour;
	foreColourChanged = true;
}

void FormatChange::setBackColour(QRgb newBackColour)
{
	backColour = newBackColour;
	backColourChanged = true;
}

void FormatChange::setAlign(Qt::Alignment newAlign)
{\
	align = newAlign;
	alignChanged = true;
}

void FormatChange::setList(int newList)
{
	list = newList;
	listChanged = true;
}

/**
  *	Converts the object to a QByteArray. Only the data where <variableName>Changed=true is kept
  */
QByteArray FormatChange::toBytes()
{
	QByteArray bytes;
	QDataStream sout(&bytes, QIODevice::WriteOnly);

	sout << operation << revisionId << userId << docId << position << num;

	if (boldChanged)
		sout << (quint8)FormatChange::BOLD << (quint8)bold;

	if (italicsChanged)
		sout << (quint8)FormatChange::ITALICS << italics;

	if (underlineChanged)
		sout << (quint8)FormatChange::UNDERLINE << underline;

	if (fontSizeChanged)
		sout << (quint8)FormatChange::FONT_SIZE << fontSize;

	if (foreColourChanged)
		sout << (quint8)FormatChange::FORE_COLOUR << (quint32)foreColour;

	if (backColourChanged)
		sout << (quint8)FormatChange::BACK_COLOUR << (quint32)backColour;

	if (alignChanged)
		sout << (quint8)FormatChange::ALIGN << (quint32)(int(align));

	if (listChanged)
		sout << (quint8)FormatChange::LIST << (quint32)list;

	//IMPORTANT: Any possibly empty strings should be dead last in messages - they can mess things up
	if (fontFamilyChanged)
		sout << (quint8)FormatChange::FONT_FAMILY << fontFamily.toAscii();

	return bytes;
}

/**
  *	Returns true when all of the properties have NOT been set (ie/ message is empty and would be useless if sent)
  */
bool FormatChange::isEmpty()
{
	if (boldChanged || italicsChanged || underlineChanged || fontSizeChanged ||
		fontFamilyChanged || foreColourChanged || backColourChanged ||
		alignChanged || listChanged)
	{
		return false;
	}

	return true;
}
